package help

import (
	"crypto/md5"
	"fmt"
	"gin_gorm_oj/define"
	"github.com/dgrijalva/jwt-go"
	uuid "github.com/satori/go.uuid"
	"io/ioutil"
	"math/rand"
	"os"
	"strconv"
	"time"
)

func GetMd5(s string) string {

	return fmt.Sprintf("%x", md5.Sum([]byte(s)))
}

type UserClaims struct {
	jwt.StandardClaims
	Name     string `json:"name"`
	Identity string `json:"identity"`
	IsAdmin  int    `json:"is_admin"`
}

var MyKey = []byte("oj")

// GenerateToken
// 生成token
func GenerateToken(identity string, name string, isAdmin int) (string, error) {
	userClaims := &UserClaims{
		StandardClaims: jwt.StandardClaims{},
		Name:           name,
		Identity:       identity,
		IsAdmin:        isAdmin,
	}
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, userClaims)
	s, err := token.SignedString(MyKey)
	if err != nil {
		return "", err
	}
	return s, nil
}

// TestAnalyseToken
// 解析token
func AnalyseToken(tokenString string) (*UserClaims, error) {
	userClaim := new(UserClaims)
	claims, err := jwt.ParseWithClaims(tokenString, userClaim, func(token *jwt.Token) (interface{}, error) {
		return MyKey, nil
	})
	if err != nil {
		return nil, err
	}
	if !claims.Valid {
		return nil, fmt.Errorf("invalid token:%v", err)
	}
	return userClaim, nil
}

// GetUUID
// 生成唯一码
func GetUUID() string {
	return uuid.NewV4().String()
}

// 生成验证码
func GetRand() string {
	rand.Seed(time.Now().UnixNano())
	s := ""
	for i := 0; i < 4; i++ {
		s += strconv.Itoa(rand.Intn(10))
	}
	return s
}

// CodeSave
// 保存代码
func CodeSave(code []byte) (string, error) {
	dirtName := "code/" + GetUUID()
	path := dirtName + "/main.go"
	err := os.Mkdir(dirtName, 077)
	if err != nil {
		return "", err
	}
	f, err1 := os.Create(path)
	if err1 != nil {
		return "", err1
	}
	f.Write(code)
	defer f.Close()
	return path, nil
}
func CheckGoCodeValid(path string) (bool, error) {
	b, err := ioutil.ReadFile(path)
	if err != nil {
		return false, err
	}
	code := string(b)
	for i := 0; i < len(code)-6; i++ {
		if code[i:i+6] == "import" {
			var flag byte
			for i = i + 7; i < len(code); i++ {
				if code[i] == ' ' {
					continue
				}
				flag = code[i]
				break
			}
			if flag == '(' {
				for i = i + 1; i < len(code); i++ {
					if code[i] == ')' {
						break
					}
					if code[i] == '"' {
						t := ""
						for i = i + 1; i < len(code); i++ {
							if code[i] == '"' {
								break
							}
							t += string(code[i])
						}
						if _, ok := define.ValidGolangPackageMap[t]; !ok {
							return false, nil
						}
					}
				}
			} else if flag == '"' {
				t := ""
				for i = i + 1; i < len(code); i++ {
					if code[i] == '"' {
						break
					}
					t += string(code[i])
				}
				if _, ok := define.ValidGolangPackageMap[t]; !ok {
					return false, nil
				}
			}
		}
	}
	return true, nil
}
